package com.brilliance.project.common.report;

import java.io.File;
import java.util.Map;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRLoader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.brilliance.project.common.exception.BaseJasperReportException;
import com.brilliance.project.common.exception.ErrorReferenceReport;

/**
 * Page/class Name: GenerateJasperPrint Title:<br />
 * 产生 JasperPrint 对象 <br />
 * Copyright: Copyright(c) Brilliance Technology<br />
 * 
 * @author HLJ
 * @version 1.0
 * @created 2012-11-24<br />
 */
public class GenerateJasperPrint {
	private static Log log = LogFactory.getLog(GenerateJasperPrint.class);

	/** 传入 JaperReport 的参数 **/
	private Map params;

	/** japserreport 模版的地址 **/
	private String reportFilePath;

	/** dataSource **/
	private JRDataSource dataSource;

	private Map<String, String> propertyMap;

	/**
	 * 
	 * @param reportFilePath
	 * @param params
	 * @param dataSource
	 * @throws BaseJasperReportException
	 */
	public GenerateJasperPrint(String reportFilePath, Map params,
			JRDataSource dataSource) throws BaseJasperReportException {
		// 传入的模板文件格式不对，请传入以.jasper为扩展名的文件
		if (reportFilePath == null || !reportFilePath.endsWith(".jasper")) {
			throw new BaseJasperReportException(
					ErrorReferenceReport.JASPERREPORT_FILENAME_FORMAT_ERROR);
		} /* end of if */
		// DataSource不可以为null
		if (dataSource == null) {
			throw new BaseJasperReportException(
					ErrorReferenceReport.JRDATASOURCE_NOT_NULL);
		} /* end of if */

		// 去除parameter中null值之字样
		for (Object tempKey : params.keySet()) {
			String key = (String) tempKey;
			if (null == params.get(key)) {
				params.put(key, "");
			}
		}
		this.setReportFilePath(reportFilePath);
		this.setParams(params);
		this.setDataSource(dataSource);
	}

	public void setReportFilePath(String reportFilePath)
			throws BaseJasperReportException {
		if (reportFilePath == null || !reportFilePath.endsWith(".jasper")) {
			throw new BaseJasperReportException(
					ErrorReferenceReport.JASPERREPORT_FILENAME_FORMAT_ERROR);
		}
		this.reportFilePath = reportFilePath;
	}

	/**
	 * 取得 JasperPrint
	 * 
	 * @return
	 * @throws BaseJasperReportException
	 */
	public JasperPrint getJasperPrint() throws BaseJasperReportException {
		File reportFile = new File(this.reportFilePath);
		JasperReport jasperReport = null;
		JasperPrint jasperPrint = null;
		// 判断传入的档案是否存在
		if (!reportFile.exists()) {
			throw new BaseJasperReportException(
					ErrorReferenceReport.JASPER_FILE_NOT_FOUND);
		} /* end of if */

		try {
			// Load 编译好的模版
			jasperReport = (JasperReport) JRLoader
					.loadObjectFromFile(reportFile.getPath());
			for (Map.Entry<String, String> entry : propertyMap.entrySet()) {
				log.debug("setProperty(" + entry.getKey() + ", "
						+ entry.getValue() + ")");
				jasperReport.setProperty(entry.getKey(), entry.getValue());
			}
			// 填入数据
			jasperPrint = JasperFillManager.fillReport(jasperReport,
					this.params, this.dataSource);
		} catch (JRException jre) {
			log.error(jre.toString());
			jre.printStackTrace();
			// 进行数据填充时发生错误
			throw new BaseJasperReportException(
					ErrorReferenceReport.JASPERREPORT_FILL_REPORT_ERROR);
		} /* end of try ... catch */
		return jasperPrint;
	}

	public Map getParams() {
		return params;
	}

	public void setParams(Map params) {
		this.params = params;
	}

	public String getReportFilePath() {
		return reportFilePath;
	}

	public Map<String, String> getPropertyMap() {
		return propertyMap;
	}

	public void setPropertyMap(final Map<String, String> propertyMap) {
		this.propertyMap = propertyMap;
	}

	public JRDataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(JRDataSource dataSource) {
		this.dataSource = dataSource;
	}
}
